package fun.shuofeng.juc.completableFuture;

import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 朔风
 * @date 2024-02-29 20:19
 */
public class CompletableFutureMallDemo {

    static List<NetMall> list = Arrays.asList(
            new NetMall("jd"),
            new NetMall("dangdang"),
            new NetMall("pdd"),
            new NetMall("moz"),
            new NetMall("tiktok"),
            new NetMall("taobao")
    );

    /**
     * 单线程，一次一次比较价格
     * @param list
     * @param productName
     * @return
     */
    public static List<String> getPrice(List<NetMall> list, String productName) {
        return list.stream()
                // .parallel()
                .map(netMall -> String.format("《%s》 in %s price is %.2f ",
                        productName,
                        netMall.getNetMallName(),
                        netMall.calcPrice(productName)))
                .collect(Collectors.toList());
    }

    /**
     * 使用CompletableFuture异步比较
     *
     * @param list
     * @param productName
     * @return
     */
    public static List<String> getPriceByCompletableFuture(List<NetMall> list, String productName) {
        return list.stream()
                .map(netMall -> CompletableFuture.supplyAsync(()->{
                    return String.format("《%s》 in %s price is %.2f ",
                            productName,
                            netMall.getNetMallName(),
                            netMall.calcPrice(productName));
                }))
                .collect(Collectors.toList()).stream()
                .map(future->{
                    return future.join();
                }).collect(Collectors.toList());
    }


    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        for (String price : getPrice(list, "mysql")) {
            System.out.println(price);
        }

        // for (String price : getPriceByCompletableFuture(list, "mysql")) {
        //     System.out.println(price);
        // }


        long end = System.currentTimeMillis();
        System.out.println("----cost time："+(end-start)+"毫秒");
    }
}


class NetMall {

    @Getter
    private String netMallName;


    public NetMall(String netMallName) {
        this.netMallName = netMallName;
    }

    public double calcPrice(String productName) {
        try {
            // 暂停一秒代表耗时
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        return productName.charAt(0) + ThreadLocalRandom.current().nextDouble() * 2;
    }

}

